﻿using System;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.Linq;

namespace Inovout.Resources
{
    internal class ConfigFile
    {
        private const string extensionName = "config";
        private const string path = "Configs";

        private readonly string name;
        private readonly Assembly assembly;


        public ConfigFile(string name)
            : this(name, Assembly.GetCallingAssembly())
        {
        }
        public ConfigFile(string name, Assembly assembly)
        {
            ArgumentAssert.IsNotDefault(name, "name");
            ArgumentAssert.IsNotNull(assembly, "assembly");
            this.name = name;
            this.assembly = assembly;
        }
        public string FulLName
        {
            get
            {
                return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}\\{1}.{2}", path, name, extensionName));
            }
        }

        public bool HasCustomConfigFile()
        {
            return File.Exists(FulLName);
        }

        public string FileFullName
        {
            get
            {
                string fileFullName;
#if DEBUG
                fileFullName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}\\{1}.debug.{2}", path, name, extensionName));

#endif
                fileFullName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}\\{1}.{2}", path, name, extensionName));

                return fileFullName;

            }
        }


        public Stream Read()
        {
            if (HasCustomConfigFile())
            {
                return ReadFromFile();
            }
            else
            {
                return ReadFromResource();
            }
        }

        private Stream ReadFromFile()
        {
            return new FileStream(FileFullName, FileMode.Open, FileAccess.Read, FileShare.None);
        }

        private Stream ReadFromResource()
        {
            string[] manifestResourceNames = assembly.GetManifestResourceNames();
            string configResourceName;
#if DEBUG
            configResourceName = string.Format("{0}.{1}.{2}.debug.{3}", assembly.GetName().Name, path, name, extensionName);
            if (!manifestResourceNames.Contains(configResourceName))
            {
                manifestResourceNames = manifestResourceNames.Where(
                    manifestResourceName => manifestResourceName.LastIndexOf(
                        string.Format("{0}.{1}.debug.{2}", path, name, extensionName)) > -1).ToArray();
                if (manifestResourceNames.Length == 1)
                {
                    configResourceName = manifestResourceNames[0];
                }
            }
#else
            configResourceName = string.Format("{0}.{1}.{2}", assembly.GetName().Name, name, extensionName);
            if (!manifestResourceNames.Contains(configResourceName))
            {
                manifestResourceNames = manifestResourceNames.Where(
                    manifestResourceName => manifestResourceName.LastIndexOf(
                        string.Format("{0}.{1}.{2}", path, name, extensionName)) > -1).ToArray();
                if (manifestResourceNames.Length == 1)
                {
                    configResourceName = manifestResourceNames[0];
                }
                else
                {
                    throw new Exception("ConfigResource not exists.");
                }
            }
#endif
            return assembly.GetManifestResourceStream(configResourceName);

        }

        //public void WriteCustomConfiFile()
        //{
        //    string configFolderName = Path.GetDirectoryName(FileFullName);
        //    if (!Directory.Exists(configFolderName))
        //    {
        //        Directory.CreateDirectory(configFolderName);
        //    }
        //    using (FileStream fileStream = new FileStream(FileFullName, FileMode.CreateNew, FileAccess.Write, FileShare.None))
        //    {
        //        using (Stream stream = Read())
        //        {
        //            fileStream.Write(stream.Read(0, (long)stream.Length)
        //                , 0, stream.Length);
        //        }
        //    }
        //}
    }
}
